#Velicer method for kPCA and PCA
setClass("VelicerDimChooser",contains="PCADimChooser",
		prototype=prototype(
				.description="Velicer DimChooser"
		)
)
#helper methods
applyFunVel <- function(x,rei,reducer){
	pcor.mat(reducer@.tmpData[x[1],],reducer@.tmpData[x[2],],rei,method="s")^2
}
applyFunVel <-cmpfun(applyFunVel)
#general functions
velicerMethod<- function(.Object,reducer,...) {
	#initial computations
	
	#transpose set pcor.mat function needs this
	reducer@.tmpData <- t(reducer@.tmpData)
	dataDims <- dim(reducer@.tmpData)
	dims <- dataDims[1]
	
	#dimension of reduced set
	#prcomp always returns number of dimensions smaller than number of odbjects
	kDims <-length(as.data.frame(reducer@.rotatedSet))
	print("kDIMS::::: ");print(kDims)
	Fk <- rep(0,kDims)
	Fk0 <-0;
	numOfDims <-1;
	
	#make computation grid (upper triangle of matrix)
	gri <-expand.grid(1:dims,1:dims)
	gri <-gri[which(gri$Var1>gri$Var2),]
	print("dimss::::");print(dims)
	
	#TODO make multicore
	print("NO MC!!!!!!!!!!");
	for (k in 1:kDims){
		reigen <-reducer@.rotatedSet[,1:k,drop=FALSE]
		result <- apply(gri,1,FUN=applyFunVel,reigen,reducer)
		Fk[k] <- sum(unlist(result))
	}
#	Fk <-unlist(foreach( k = seq(from=1,to=kDims,by=1) )%dopar%{
#				reigen <-reducer@.rotatedSet[,1:k,drop=FALSE]
#				result <- apply(gri,1,FUN=applyFunVel,reigen,reducer)
#				summ <-sum(unlist(result))
#				gc()
#				return(summ)
#			}
#			)
	#compute Fk0
	reducer@.tmpData <- t(reducer@.tmpData)
	dCor <- cor(reducer@.tmpData,reducer@.tmpData)
	dCor <-dCor -diag(diag(dCor))
	Fk0 <- sum(dCor*dCor)/{2*{dims*{dims-1}}}
	#remove NA or NAN values
	Fk <-Fk[is.finite(Fk)]
	Fk <- Fk/{dims*{dims-1}}
	
	numOfDims <- which.min(Fk);
	if(Fk0 <Fk[1]){
		warning("None of eigenvalues seem to be significant ",.Object@.description," ",reducer@.description)
	}
	
	return(as.integer(numOfDims))
}
#methods
setMethod("chooseBest",
		signature=c("VelicerDimChooser","PCAReducer"),
		definition= velicerMethod
)


setMethod("chooseBest",
		signature=c("VelicerDimChooser","kPCAReducer"),
		definition= velicerMethod
)

